/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#ifndef __AP_BARO_BMP085_H__
#define __AP_BARO_BMP085_H__

#include <stdint.h>

#define PRESS_FILTER_SIZE 2

//#include "AP_Baro.h"
//#include <AverageFilter.h>

#define  PRESS_ACQ_TIME   200        // Pressure sample time, unit in ms
#define  TEMP_ACQ_TIME    1000       // Temperature sample time,unit in ms


/* ---- Registers ---- */
#define CAL_AC1           0xAA  // R   Calibration data (16 bits)
#define CAL_AC2           0xAC  // R   Calibration data (16 bits)
#define CAL_AC3           0xAE  // R   Calibration data (16 bits)    
#define CAL_AC4           0xB0  // R   Calibration data (16 bits)
#define CAL_AC5           0xB2  // R   Calibration data (16 bits)
#define CAL_AC6           0xB4  // R   Calibration data (16 bits)
#define CAL_B1            0xB6  // R   Calibration data (16 bits)
#define CAL_B2            0xB8  // R   Calibration data (16 bits)
#define CAL_MB            0xBA  // R   Calibration data (16 bits)
#define CAL_MC            0xBC  // R   Calibration data (16 bits)
#define CAL_MD            0xBE  // R   Calibration data (16 bits)
#define CONTROL           0xF4  // W   Control register 
#define CONTROL_OUTPUT    0xF6  // R   Output registers 0xF6=MSB, 0xF7=LSB, 0xF8=XLSB

// unused registers
#define SOFTRESET         0xE0
#define VERSION           0xD1  // ML_VERSION  pos=0 len=4 msk=0F  AL_VERSION pos=4 len=4 msk=f0
#define CHIPID            0xD0  // pos=0 mask=FF len=8
                                // BMP085_CHIP_ID=0x55
/************************************/
/*    REGISTERS PARAMETERS          */
/************************************/
// BMP085 Modes
#define MODE_ULTRA_LOW_POWER    0 //oversampling=0, internalsamples=1, maxconvtimepressure=4.5ms, avgcurrent=3uA, RMSnoise_hPA=0.06, RMSnoise_m=0.5
#define MODE_STANDARD           1 //oversampling=1, internalsamples=2, maxconvtimepressure=7.5ms, avgcurrent=5uA, RMSnoise_hPA=0.05, RMSnoise_m=0.4
#define MODE_HIGHRES            2 //oversampling=2, internalsamples=4, maxconvtimepressure=13.5ms, avgcurrent=7uA, RMSnoise_hPA=0.04, RMSnoise_m=0.3
#define MODE_ULTRA_HIGHRES      3 //oversampling=3, internalsamples=8, maxconvtimepressure=25.5ms, avgcurrent=12uA, RMSnoise_hPA=0.03, RMSnoise_m=0.25
                  // "Sampling rate can be increased to 128 samples per second (standard mode) for
                  // dynamic measurement.In this case it is sufficient to measure temperature only 
                  // once per second and to use this value for all pressure measurements during period."
                  // (from BMP085 datasheet Rev1.2 page 10).
                  // To use dynamic measurement set AUTO_UPDATE_TEMPERATURE to false and
                  // call calcTrueTemperature() from your code. 
// Control register
#define READ_TEMPERATURE        0x2E 
#define READ_PRESSURE           0x34 
//Other
#define MSLP                    101325          // Mean Sea Level Pressure = 1013.25 hPA (1hPa = 100Pa = 1mbar)

// oversampling at highest resolution
#define OVERSAMPLING    MODE_ULTRA_HIGHRES

class AP_Baro_BMP085
{
  public:
    AP_Baro_BMP085(void) {};// Constructor
  
    // BMP initialization
    void init(void);                                  // sets current elevation above ground level to 0 meters
#if 0
    void init(int32_t _initVal, bool _centimeters);   // sets a reference datum
                                                      // if _centimeters=false _initVal is Pa 
#endif    
    /* AP_Baro public interface: */

    void RefreshData(void); // refresh loop
    int32_t get_pressure();
    int16_t get_temperature();
    int32_t get_altitude(); // unit in CM

    int32_t get_raw_pressure();
    int32_t get_raw_temp();

    // Clibration
#if 0
    void setLocalPressure(int32_t _Pa);            // set known barometric pressure as reference Ex. QNH
    void setLocalAbsAlt(int32_t _centimeters);     // set known altitude as reference
    void setAltOffset(int32_t _centimeters);       // altitude offset
    void sethPaOffset(int32_t _Pa);                // pressure offset
    void zeroCal(int32_t _Pa, int32_t _centimeters);// zero Calibrate output to a specific Pa/altitude
#endif    
  private:
    int32_t RawPress;
    int32_t RawTemp;
    int16_t Temp;
    uint32_t Press;
    int32_t  Altitude;
    int32_t _cm_Offset, _Pa_Offset;
    int32_t _param_datum, _param_centimeters;
    int32_t b5;
    // State machine
    uint8_t PressState,TempState,BMP085_in_Used;
    // Internal calibration registers
    int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
    uint16_t ac4, ac5, ac6;
    uint8_t healthy;
    // AverageFilterInt32_Size4 _temp_filter;
    
    uint16_t PressTimer,TempTimer;
    void GetCalData(void); 
//    void Command_ReadPress(void);
//    void Command_ReadTemp(void);
    void UpdatePress(void);
    void UpdateTemp(void);
    void calcTrueTemperature(void);
    void CalculatePress(int32_t PressRaw);
    void CalculateAltitude(uint32_t PressIn);
};

#endif // __AP_BARO_BMP085_H__
